package cn.lut.da01;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @user:dell
 * @date:2020年10月29 20:22
 */
/**
 *  @Aspect : 是aspectj框架中的注解。
 *     作用：表示当前类是切面类。
 *     切面类：是用来给业务方法增加功能的类，在这个类中有切面的功能代码
 *     位置：在类定义的上面
 */
@Component("myAspect")
@Aspect

public class MyAspect {
    /**
     * 定义方法，方法是实现切面功能的。
     * 方法的定义要求：
     * 1.公共方法 public
     * 2.方法没有返回值
     * 3.方法名称自定义
     * 4.方法可以有参数，也可以没有参数。
     *   如果有参数，参数不是自定义的，有几个参数类型可以使用。
     */


    /**
     * @Before: 前置通知注解
     *   属性：value ，是切入点表达式，表示切面的功能执行的位置。
     *   位置：在方法的上面
     * 特点：
     *  1.在目标方法之前先执行的
     *  2.不会改变目标方法的执行结果
     *  3.不会影响目标方法的执行。
     */
//    @Before(value = "execution(public void cn.lut.da01.impl.SomeServiceImpl.doSome(String,int))")
//    public void myBefore(){
//        System.out.println("前置通知，执行时间："+new Date());
//    }


//    @Before(value = "execution( void cn.lut.da01.impl.SomeServiceImpl.doSome(String,int))")
//    public void myBefore(){
//        System.out.println("1===前置通知，执行时间："+new Date());
//    }

//
//    @Before(value = "execution( void *..SomeServiceImpl.doSome(String,int))")
//    public void myBefore(){
//        System.out.println("2===前置通知，执行时间："+new Date());
//    }

//    @Before(value = "execution( * *..SomeServiceImpl.doSome(String,int))")
//    public void myBefore(){
//        System.out.println("3===前置通知，执行时间："+new Date());
//    }

//    @Before(value = "execution( * *..SomeServiceImpl.do*(String,int))")
//    public void myBefore(){
//        System.out.println("4===前置通知，执行时间："+new Date());
//    }
    /**
     * 指定通知方法中的参数 ： JoinPoint
     * JoinPoint:业务方法，要加入切面功能的业务方法
     *    作用是：可以在通知方法中获取方法执行时的信息， 例如方法名称，方法的实参。
     *    如果你的切面功能中需要用到方法的信息，就加入JoinPoint.
     *    这个JoinPoint参数的值是由框架赋予， 必须是第一个位置的参数
     */
        @Before(value = "execution( void *..SomeServiceImpl.doSome(String,int))")
    public void myBefore(JoinPoint joinPoint){
            System.out.println("方法的签名是:"+joinPoint.getSignature());
            System.out.println("方法的名字是:"+joinPoint.getSignature().getName());
//            获取参数的实参
            Object[] args = joinPoint.getArgs();
            for (Object arg : args) {
                System.out.println(arg);
            }
            System.out.println("2===前置通知，执行时间："+new Date());
    }

}
